]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
keyboardManager: Avoid duplicating locale layout in groups
authorYan Pas <yanp.bugz@gmail.com>
Sun, 26 Jul 2026 01:19:21 +0000 (02:19 +0100)
committerFlorian Müllner <fmuellner@gnome.org>
Sun, 13 Sep 2026 17:39:10 +0000 (19:39 +0200)
XKB is limited to 4 kb layout. In gnome-shell we used to store maximum
3 + locale layout. This PR adds check for duplication. Resulting in a
better support when user has 4 layouts.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4256>
(cherry picked from commit 9d6e88dcdce4aa1f904b59b20089d49bdc763a57)

js/misc/keyboardManager.js

index c056cc0345fe62f62be6bc1314a9cbd383cba95e..77dd6da0dba5cd47b8996a552071cc59e16bce54 100644 (file)
@@ -190,24 +190,26 @@ class KeyboardManager extends Signals.EventEmitter {
             }
         }
 
-        let i = 0;
         let group = [];
-        for (const id in this._layoutInfos) {
-            // We need to leave one slot on each group free so that we
-            // can add a layout containing the symbols for the
-            // language used in UI strings to ensure that toolkits can
-            // handle mnemonics like Alt+Ф even if the user is
-            // actually typing in a different layout.
-            const groupIndex = i % (this.MAX_LAYOUTS_PER_GROUP - 1);
-            if (groupIndex === 0)
+        for (const id of ids) {
+            const info = this._layoutInfos[id];
+            if (!info)
+                continue;
+
+            const isLocale = this._isLocaleLayout(info);
+            const hasLocale = group.some(g => this._isLocaleLayout(g));
+
+            // We need to leave one slot on the group free if we haven't included
+            // the locale layout yet. This ensures we can add a layout containing
+            // the symbols for the language used in UI strings.
+            if (group.length === this.MAX_LAYOUTS_PER_GROUP ||
+                (group.length === this.MAX_LAYOUTS_PER_GROUP - 1 && !hasLocale && !isLocale))
                 group = [];
 
-            const info = this._layoutInfos[id];
-            group[groupIndex] = info;
+            const groupIndex = group.length;
+            group.push(info);
             info.group = group;
             info.groupIndex = groupIndex;
-
-            i += 1;
         }
     }
 
@@ -231,14 +233,25 @@ class KeyboardManager extends Signals.EventEmitter {
             return {layout: DEFAULT_LAYOUT, variant: DEFAULT_VARIANT};
     }
 
+    /**
+     * @param {LayoutInfo} info
+     * @returns {boolean}
+     */
+    _isLocaleLayout(info) {
+        return info.layout === this._localeLayoutInfo.layout &&
+            info.variant === this._localeLayoutInfo.variant;
+    }
+
     /**
      * Builds the comma-separated layout and variant strings for a given group of layouts.
      *
-     * @param {LayoutInfo[]} _group - The array of layouts currently in this chunk.
+     * @param {LayoutInfo[]} group - The array of layouts currently in this chunk.
      * @returns {[string, string]} A tuple containing the combined layout string and variant string.
      */
-    _buildGroupStrings(_group) {
-        const group = _group.concat(this._localeLayoutInfo);
+    _buildGroupStrings(group) {
+        if (!group.some(g => this._isLocaleLayout(g)))
+            group = group.concat(this._localeLayoutInfo);
+
         const layouts = group.map(g => g.layout).join(',');
         const variants = group.map(g => g.variant).join(',');
         return [layouts, variants];